﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics.Contracts;
using System.ServiceModel;
using MicropleSoft.WmsServiceLibrary.Cache;
using MicropleSoft.WmsServiceLibrary.Common;
using MicropleSoft.WmsServiceLibrary.Domain;
using MicropleSoft.WmsServiceLibrary.Util;

namespace MicropleSoft.WmsServiceLibrary.Security
{
    public class Authentication : IAuthentication
    {
        private readonly IWmsUserService _wmsUserService = null;
        private readonly IUserWhService _userWhService = null;
        private readonly IUserTokenListService _userTokenListService = null;

        public Authentication()
        {
            _wmsUserService = StaticBean.CreateAbstractServiceFactory().CreateWmsUserService();
            _userWhService = StaticBean.CreateAbstractServiceFactory().CreateUserWhService();
            _userTokenListService = StaticBean.CreateAbstractServiceFactory().CreateUserTokenListService();
        }
        #region Implementation of IAuthentication

        public string Login(string userId, string password,string whId)
        {
            try
            {
                if (String.IsNullOrEmpty(userId) || String.IsNullOrEmpty(password) || String.IsNullOrEmpty(whId))
                {
                    return "用户、密码、机构代码不能为空！";
                }

                string condition = " and USER_ID ='{0}'";
                condition = string.Format(condition, StaticUtil.ConvertInjectString(userId));
                var list = _wmsUserService.Query(condition);
                if (list.Count == 0)
                {
                    return string.Format("无此用户{0}！", userId);
                }
                else
                {
                    var user = list[0];
                    if (user.Passwd.ToUpper() ==Cryptographer. CryptoMd5(password).ToUpper())
                    {
                        if (user.ExpireDate != null)
                        {
                            var dt = (DateTime)user.ExpireDate;
                            if (dt < DateTime.Now)
                            {
                                return string.Format("用户{0}已经过期！", userId);
                            }
                        }

                        string con = " and USER_ID='{0}' and WH_ID ='{1}'  ";
                        con = string.Format(con, StaticUtil.ConvertInjectString(userId), StaticUtil.ConvertInjectString(whId));
                        var userWhList = _userWhService.Query(con);
                        if (userWhList.Count == 0)
                        {
                            return string.Format("用户{0}不属于仓库{1}！", userId, whId);
                        }
                        else
                        {
                            string sessionId = Guid.NewGuid().ToString("N");
                            string token = "token:" + Cryptographer.EncryptDES(sessionId, Cryptographer.GetEncryptKey());
                            //var userTokenList = UserTokenList.CreateUserTokenList();
                            //userTokenList.CreateTime = DateTime.Now;
                            //userTokenList.SessionId = sessionId;
                            //userTokenList.UserId = user.UserId;
                            //userTokenList.UserName = user.UserName;
                            //userTokenList.DomainObjectState = DomainEntityState.Added;
                            ////该字段记录此sessionid从数据库中刷过多少次，每一次当cache中不存在的时候就刷
                            //userTokenList.ObligateNumeric1 = 1;
                            //_userTokenListService.Save(new List<IUserTokenList>() { userTokenList });
                            DataCacheManager.SetSessionKey(sessionId);
                            DataCacheManager.SetUserId(sessionId, user.UserId);
                            DataCacheManager.SetUserName(sessionId, user.UserName);
                            return token;
                        }
                    }
                    return "密码错误！";
                }
            }
            catch (Exception ex)
            {
                return Exceptions.ExceptionHandler.GetDetialException(ex);
            }
        }

        public void ValidateToken(string token)
        {
            string sessionId = String.Empty;
            try
            {
                sessionId = Cryptographer.DecryptDES(token, Cryptographer.GetEncryptKey());
            }
            catch (Exception )
            {
                 Exceptions.ExceptionHandler.ThrowException("非法token！");
            }

            //查询缓存，如果不存在，则查询数据库
            if(!DataCacheManager.ContainSessionKey(sessionId))
            {
                //查询数据库，如果不存在，报错，如果存在，则重新塞入缓存，同时更新updatetime
                var list = _userTokenListService.Query(string.Format(" and SESSION_ID='{0}'",sessionId));
                if(list.Count >0)
                {
                    var tmp = list[0];
                    if (DateTime.Now - tmp.CreateTime > new TimeSpan(7, 0, 0, 0))
                    {
                        Exceptions.ExceptionHandler.ThrowException("登录token已经超过7天，为了安全，请重新登录！");
                    }

                    tmp.UpdateTime = DateTime.Now;
                    tmp.ObligateNumeric1 = tmp.ObligateNumeric1 + 1;
                    tmp.DomainObjectState = DomainEntityState.Updated;

                    _userTokenListService.Save(new List<IUserTokenList>(){tmp});
                    DataCacheManager.SetSessionKey(sessionId);
                    DataCacheManager.SetUserId(sessionId, tmp.UserId);
                    DataCacheManager.SetUserName(sessionId, tmp.UserName);
                }
                else
                {
                    Exceptions.ExceptionHandler.ThrowException("非法token，或者token已经过期，请重新登录！");
                }
            }
        }

        public string GetCurrentUserId(string token)
        {
            string sessionId = String.Empty;
            try
            {
                sessionId = Cryptographer.DecryptDES(token, Cryptographer.GetEncryptKey());
            }
            catch (Exception)
            {
                 Exceptions.ExceptionHandler.ThrowException("非法token！");
            }
            string userId= DataCacheManager.GetUserId(sessionId);
            if(string.IsNullOrEmpty(userId))
            {
                ValidateToken(token);
                return GetCurrentUserId(token);
            }
            return userId;
        }

        public string GetCurrentUserName(string token)
        {
            string sessionId = String.Empty;
            try
            {
                sessionId = Cryptographer.DecryptDES(token, Cryptographer.GetEncryptKey());
            }
            catch (Exception)
            {
                 Exceptions.ExceptionHandler.ThrowException("非法token！");
            }
            string userName = DataCacheManager.GetUserName(sessionId);
            if (string.IsNullOrEmpty(userName))
            {
                ValidateToken(token);
                return GetCurrentUserName(token);
            }
            return userName;
        }

        public void ValidateToken()
        {
            ValidateToken(GetContextToken());
        }

        public string GetContextToken()
        {
            var token = OperationContext.Current.IncomingMessageHeaders.GetHeader<String>("token", "ns");
            return token;
        }

        public string GetCurrentUserId()
        {
            return GetCurrentUserId(GetContextToken());
        }

        public string GetCurrentUserName()
        {
            return GetCurrentUserName(GetContextToken());
        }
        #endregion
    }
}